package cn.seaboot.admin.upload;

import cn.seaboot.commons.core.Asserts;
import cn.seaboot.commons.core.CommonUtils;
import cn.seaboot.commons.file.FileUtils;
import cn.seaboot.commons.file.FilenameUtils;
import cn.seaboot.commons.file.IOUtils;
import org.jetbrains.annotations.NotNull;

import java.io.*;

/**
 * 本机文件存储
 * <p>
 * 提供最核心的 IO 操作，方便后续程序进行功能扩展.
 *
 * @author Mr.css
 * @version 2023-08-24 15:44
 */
public class LocalStorage implements Storage {

    private final File root;

    public LocalStorage(File root) {
        this.root = root;
    }

    @Override
    public String write(InputStream is, String path) throws IOException {
        File out = file(path);
        if (out.exists()) {
            throw new IOException("file exist: " + out.getName());
        } else {
            FileUtils.file(out);
            FileUtils.copyFile(is, out);
            return path;
        }
    }

    @Override
    public void delete(String path) throws IOException {
        File file = file(path);
        if (file.exists() && file.delete()) {
            throw new IOException("delete file failed：" + path);
        }
    }

    @Override
    public void overwrite(InputStream is, String path) throws IOException {
        File out = file(path);
        FileUtils.copyFile(is, out);
    }

    @Override
    public @NotNull File getFile(String path) throws IOException {
        return file(path);
    }

    @Override
    public @NotNull InputStream openInputStream(String path) throws IOException {
        File file = file(path);
        return IOUtils.openFileInputStream(file);
    }

    @Override
    public void copy(String path, OutputStream os) throws IOException {
        File file = file(path);
        try (InputStream is = IOUtils.openFileInputStream(file)) {
            IOUtils.copy(is, os);
        }
    }

    private File file(String path) throws FileNotFoundException {
        if(CommonUtils.isEmpty(path)) {
            throw new FileNotFoundException("file is not found!");
        }
        FilenameUtils.validFilePath(path, "invalid file path!");
        return new File(root, path);
    }
}
